package com.liuning.websocketdemo.websocket;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.liuning.websocketdemo.config.GetHttpSessionConfigurator;
import com.liuning.websocketdemo.pojo.Message;
import com.liuning.websocketdemo.pojo.MessageUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfigurator.class)
@Component
public class ChatEndPoint {

    //用来存储每一个客户端对象对应的ChatEndPoint对象
    private static Map<String,ChatEndPoint> onlineUsers = new ConcurrentHashMap<>();

    //声明session对象，通过该对象可以发送消息给指定的用户
    private Session session;

    //声明一个HttpSession，因为之前在登录成功时，在session中存储了用户名
    private HttpSession httpSession;

    @OnOpen
    public void  onOpen(Session session, EndpointConfig config) {
        this.session = session;
        HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        this.httpSession = httpSession;

        //从httpSession中获取用户名
        String username = (String) httpSession.getAttribute("user");
        //将当前对象存储到在线Map中
        onlineUsers.put(username,this);
        //将当前在线用户的用户名推送给所以的客户端
        //1、获取消息
        String message = MessageUtils.getMessage(true, null, getNames());
        //调用方法进行系统消息的推送
        broadcastAllUsers(message);

    }

    /**
     * 进行系统消息的推送
     * @param message
     */
    private void broadcastAllUsers(String message) {
        try {
            //要将该消息推送给所有的客户端
            Set<String> names = onlineUsers.keySet();
            for (String name : names) {
                ChatEndPoint chatEndPoint = onlineUsers.get(name);
                chatEndPoint.session.getBasicRemote().sendText(message);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取所有的用户名
     * @return
     */
    private Set<String> getNames() {
        return onlineUsers.keySet();
    }

    /**
     * 接受客户端发送过来的数据
     * @param message
     * @param session
     */
    @OnMessage
    public void onMessage(String message,Session session) {
        try {
            //将客户端发送过来的message进行格式转换
            ObjectMapper mapper = new ObjectMapper();
            Message mess = mapper.readValue(message, Message.class);
            //获取要接受人的用户名和消息
            String toName = mess.getToName();
            String data = mess.getMessage();
            //获取当前登录的对象(即发送消息的用户)
            String username = (String) httpSession.getAttribute("user");
            //将要发送的数据格式进行转换
            String resultMessage = MessageUtils.getMessage(false, username, data);
            //发送数据
            onlineUsers.get(toName).session.getBasicRemote().sendText(resultMessage);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @OnError
    public void onError(Session session,Throwable throwable) {

    }

    @OnClose
    public void onClose(Session session) {
        String username = (String) httpSession.getAttribute("user");
        //从在线用户中移除
        onlineUsers.remove(username);
        //将当前用户退出的消息广播给在线用户
        String message = MessageUtils.getMessage(true, null, getNames());
        broadcastAllUsers(message);

    }
}
